﻿package com.yy.tools.graphics
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	/**
	 * 九宫格图片切割
	 * @author YY
	 * 
	 */
	public class Scale9GridDisplayObject extends Sprite
	{
		private var rect:Rectangle;
		
		private var part00 : DisplayObject;
		private var part01 : DisplayObject;
		private var part02 : DisplayObject;
		private var part10 : DisplayObject;
		private var part11 : DisplayObject;
		private var part12 : DisplayObject;
		private var part20 : DisplayObject;
		private var part21 : DisplayObject;
		private var part22 : DisplayObject;
		
		private var _width : Number;
		private var _height : Number;
		
		private var _minWidth : Number;
		private var _minHeight : Number;
		
		private var sourceData:BitmapData;
		

		public function Scale9GridDisplayObject(source:DisplayObject,scale9GridRectangle:Rectangle = null) 
		{
			super();
			if(source is BitmapData){
				this.sourceData = BitmapData(source);
			}else{
				this.sourceData = new BitmapData(source.width+0.99999,source.height+0.99999,true,0);
				this.sourceData.draw(source);
			}
			
			if(scale9GridRectangle!=null){
				rect = scale9GridRectangle;
			}else if(null == source.scale9Grid){
				rect = new Rectangle(0,0,sourceData.width,sourceData.height);
			}else{
				rect = source.scale9Grid.clone();
			}
			
			_width = sourceData.width;
			_height = sourceData.height;
			
			part00 = getBitmap(0, 0, rect.left, rect.top);
			part01 = getBitmap(0, rect.top, rect.left, rect.height);
			part02 = getBitmap(0, rect.bottom, rect.left, height - rect.bottom);
			part10 = getBitmap(rect.x, 0, rect.width, rect.y);
			part11 = getBitmap(rect.x, rect.y, rect.width, rect.height);
			part12 = getBitmap(rect.x, rect.bottom, rect.width, height - rect.bottom);
			part20 = getBitmap(rect.right, 0, width - rect.right, rect.y);
			part21 = getBitmap(rect.right, rect.top, width - rect.right, rect.height);
			part22 = getBitmap(rect.right, rect.bottom, width - rect.right, height - rect.bottom);
			
			this.sourceData.dispose();
			this.sourceData = null;
			
			_minWidth = (part00==null?0:part00.width) + (part22==null?0:part22.width);
			_minHeight = (part02==null?0:part02.height) + (part22==null?0:part22.height);
			
			
			this.update(0,0);			
			
		}
		
		private function getBitmap(x:Number, y:Number, w:Number, h:Number) : DisplayObject {
			if(w<=0||h<=0){
				return null;
			}
			var bit:BitmapData = new BitmapData(w, h,true,0);
			bit.copyPixels(this.sourceData, new Rectangle(x, y, w, h), new Point(0, 0));
			var bmp:Bitmap = new Bitmap(bit,PixelSnapping.NEVER);
			bmp.x = x;
			bmp.y = y;
			this.addChild(bmp);
			return bmp;
		}
		
		override public function set width(w : Number) : void {
			var oldW:Number = this.width;
			if(w < minWidth) {
				w = minWidth;
			}
			_width = int(w);
			update(this.width-oldW,0);
		}
		
		override public function set height(h : Number) : void {
			var oldH:Number = this.height;
			if(h < minHeight) {
				h = minHeight;
			}
			_height = int(h);
			update(0,this.height-oldH);
		}
		
		override public function get width():Number{
			return _width;
		}
		
		override public function get height():Number{
			return _height;
		}
		
		public static function diff(obj:Object,property:String,diff:Number):void{
			if(obj!=null){
				obj[property]=obj[property]+diff;
			}
		}
		
		private function update(diffW:Number,diffH:Number) : void {
			if(diffW!=0){
				diff(this.rect,"width",diffW);
				diff(this.part10,"width",diffW);
				diff(this.part11,"width",diffW);
				diff(this.part12,"width",diffW);
				diff(this.part20,"x",diffW);
				diff(this.part21,"x",diffW);
				diff(this.part22,"x",diffW);
			}
			if(diffH!=0){
				diff(this.rect,"height",diffH);
				diff(this.part01,"height",diffH);
				diff(this.part11,"height",diffH);
				diff(this.part21,"height",diffH);
				diff(this.part02,"y",diffH);
				diff(this.part12,"y",diffH);
				diff(this.part22,"y",diffH);				
			}
		}
		override public function get scale9Grid():Rectangle{
			return this.rect; 
		}
		
		public function get minWidth():Number{
			return this._minWidth;
		}
		
		public function get minHeight():Number{
			return this._minHeight;
		}
		
		public function get innerBound():Rectangle{
			return this.rect;
		}
	}
}